package com.nmgydy.service;

import com.alibaba.fastjson.JSON;
import com.nmgydy.model.Court;
import com.nmgydy.model.EventItem;
import com.nmgydy.model.MoveHistory;
import com.nmgydy.util.Functions;
import com.nmgydy.util.HibernateDao;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class EventItemService {

    @Resource
    private HibernateDao hibernateDao;

    public void overToday(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Session session = null;
        Transaction transaction = null;
        try {
            session = hibernateDao.getSessionFactory().openSession();
            transaction = session.beginTransaction();
            String hql = "select m from MoveHistory m,Court c where m.courtId=c.id and m.status!='2' and c.taskId=m.taskId";
            List<MoveHistory> moveHistoryList = session.createQuery(hql).list();
            Map<MoveHistory,Integer> moveHistoryDaysMap = new HashMap<>();
            for(MoveHistory moveHistory : moveHistoryList){
                int days = dayOffset(sdf.parse(moveHistory.getUpdateTime()));
                if(days > 0){
                    moveHistoryDaysMap.put(moveHistory,days);
                }
            }
            System.out.println("moveHistoryDaysMap:"+ JSON.toJSONString(moveHistoryDaysMap));
            if(moveHistoryDaysMap.size() <= 0){
                return;
            }
            String sql = "drop table if exists tmp_move_days";
            session.createSQLQuery(sql).executeUpdate();
            sql = "create temporary table tmp_move_days like tpl_move_days";
            session.createSQLQuery(sql).executeUpdate();

            sql = "insert into tmp_move_days(courtId,taskId,historyId,days) values(:courtId,:taskId,:historyId,:days)";
            for(MoveHistory moveHistory : moveHistoryDaysMap.keySet()){
                int days = moveHistoryDaysMap.get(moveHistory);
                session.createSQLQuery(sql)
                        .setParameter("courtId",moveHistory.getCourtId())
                        .setParameter("taskId",moveHistory.getTaskId())
                        .setParameter("historyId",moveHistory.getId())
                        .setParameter("days",days)
                        .executeUpdate();
            }
            //更新天数
            String now = sdf.format(new Date());
            sql = "update cn_move_history h inner join tmp_move_days d on h.id=d.historyId" +
                    " set h.curDays=h.curDays+d.days,h.updateTime=:updateTime";
            session.createSQLQuery(sql).setParameter("updateTime",now).executeUpdate();
            sql = "update cn_court c inner join tmp_move_days d on c.id=d.courtId" +
                    " set c.curDays=c.curDays+d.days,c.updateTime=:updateTime" +
                    " where c.taskId=d.taskId";
            session.createSQLQuery(sql).setParameter("updateTime",now).executeUpdate();
            sql = "update cn_event_item e inner join tmp_move_days d on e.courtId=d.courtId" +
                    " set e.overdueDays=e.overdueDays+d.days,e.updateTime=:updateTime" +
                    " where e.eventType='2' and e.taskId=d.taskId";
            session.createSQLQuery(sql).setParameter("updateTime",now).executeUpdate();

            //查找逾期事件
            hql = "from Court where curDays>totDays and status='1'";
            List<Court> overtimeCourtList = session.createQuery(hql).list();
            for(Court court : overtimeCourtList){
                EventItem eventItem = new EventItem();
                eventItem.fillWithCourt(court);
                eventItem.setEventType("2");//逾期事件
                eventItem.setRemainDays(0);
                eventItem.setOverdueDays(court.getCurDays()-court.getTotDays());
                eventItem.setStatus("1");
                eventItem.setCreateTime(Functions.getTimeNow());
                eventItem.setUpdateTime(eventItem.getCreateTime());
                //System.out.println(JSON.toJSONString(eventItem));
                session.save(eventItem);
            }

            //查找预警事件
            hql = "from Court where (curDays=totDays-1 or totDays=curDays) and status='1' and curDays>0";
            List<Court> alertCourtList = session.createQuery(hql).list();
            for(Court court : alertCourtList){
                EventItem eventItem = new EventItem();
                eventItem.fillWithCourt(court);
                eventItem.setEventType("1");//预警事件
                eventItem.setRemainDays(court.getTotDays()-court.getCurDays());
                eventItem.setOverdueDays(0);
                eventItem.setStatus("0");
                eventItem.setCreateTime(Functions.getTimeNow());
                eventItem.setUpdateTime(eventItem.getCreateTime());
                session.save(eventItem);
            }

            //更新状态
            sql = "update cn_move_history set status='3' where curDays>totDays";
            session.createSQLQuery(sql).executeUpdate();
            sql = "update cn_court set status='3' where curDays>totDays";
            session.createSQLQuery(sql).executeUpdate();

            sql = "drop table if exists tmp_move_days";
            session.createSQLQuery(sql).executeUpdate();
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
        } finally {
            if(session != null){
                session.close();
            }
        }


    }

    public int dayOffset(Date startDay){
        Date today = new Date();
        if(today.before(startDay)){
            return 0;
        }
        int days = 0;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDay);
        calendar.add(Calendar.DATE,1);
        Date nextDay = calendar.getTime();
        while(nextDay.before(today)){
            calendar.add(Calendar.DATE,1);
            nextDay = calendar.getTime();
            days++;
        }
        return days;
    }

}
